namespace RBAC.Read.Api.Application.Handler.BomHandler
{
    using MediatR;
    using Microsoft.Extensions.Logging;
    using NPOI.SS.UserModel;
    using NPOI.XSSF.UserModel;
    using RBAC.Domain.BomManage;
    using RBAC.Interstructrue.Base;
    using RBAC.Read.Api.Application.Command.BomCommand;
    using RBAC.Read.Api.Application.Dto;

    /// <summary>
    /// 产品导出处理器（沿用分页条件：PageIndex、PageSize、OrderBy）
    /// </summary>
    public class GetProductExportHandler : IRequestHandler<GetProductExportCommand, FileExportResult>
    {
        private readonly IBaseRepository<Product> repository;
        private readonly ILogger<GetProductExportHandler> logger;

        public GetProductExportHandler(IBaseRepository<Product> repository, ILogger<GetProductExportHandler> logger)
        {
            this.repository = repository;
            this.logger = logger;
        }

        /// <summary>
        /// 处理产品导出请求，按分页条件取数并生成 .xlsx 文件字节流。
        /// </summary>
        public Task<FileExportResult> Handle(GetProductExportCommand request, CancellationToken cancellationToken)
        {
            var result = new FileExportResult();
            try
            {
                cancellationToken.ThrowIfCancellationRequested();

                logger.LogInformation("开始导出产品，PageIndex={PageIndex}, PageSize={PageSize}, OrderBy={OrderBy}", request.PageIndex, request.PageSize, request.OrderBy);

                // 按分页条件读取数据
                var (data, total) = repository.GetPaged(request.PageIndex, request.PageSize, string.Empty, request.OrderBy, null);
                var list = data.ToList();

                // 创建 Excel
                using var workbook = new XSSFWorkbook();
                var sheet = workbook.CreateSheet("产品");

                // 表头（不显示 Id，新增 创建时间）
                var header = sheet.CreateRow(0);
                header.CreateCell(0).SetCellValue("产品编码");
                header.CreateCell(1).SetCellValue("产品名称");
                header.CreateCell(2).SetCellValue("型号/规格");
                header.CreateCell(3).SetCellValue("描述");
                header.CreateCell(4).SetCellValue("创建时间");

                // 数据行
                for (int i = 0; i < list.Count; i++)
                {
                    cancellationToken.ThrowIfCancellationRequested();
                    var p = list[i];
                    var row = sheet.CreateRow(i + 1);
                    row.CreateCell(0).SetCellValue(p.Code ?? string.Empty);
                    row.CreateCell(1).SetCellValue(p.Name ?? string.Empty);
                    row.CreateCell(2).SetCellValue(p.Model ?? string.Empty);
                    row.CreateCell(3).SetCellValue(p.Description ?? string.Empty);
                    row.CreateCell(4).SetCellValue(p.CreateTime.ToString("yyyy-MM-dd HH:mm:ss"));
                }

                // 自动列宽（简单处理，避免超长耗时）
                for (int c = 0; c <= 4; c++)
                {
                    sheet.AutoSizeColumn(c);
                }

                using var ms = new System.IO.MemoryStream();
                workbook.Write(ms, leaveOpen: true);
                result.Bytes = ms.ToArray();
                result.ContentType = "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet";
                result.FileName = $"产品导出_{System.DateTime.Now:yyyyMMddHHmmss}.xlsx";

                logger.LogInformation("产品导出完成，本次导出 {Count} 条（总数 {Total}）", list.Count, total);
            }
            catch (OperationCanceledException)
            {
                logger.LogWarning("产品导出被取消");
                result.Bytes = System.Array.Empty<byte>();
                result.ContentType = "application/octet-stream";
                result.FileName = string.Empty;
            }
            catch (Exception ex)
            {
                logger.LogError(ex, "产品导出失败: {Message}", ex.Message);
                result.Bytes = System.Array.Empty<byte>();
                result.ContentType = "application/octet-stream";
                result.FileName = string.Empty;
            }

            return Task.FromResult(result);
        }
    }
}
